#ifndef _FINGER_APP_H_
#define _FINGER_APP_H_

#include "finger_api.h"

#if (_SAFETY_MODULE_TYPE_ == _FINGER_SAFETY_MODULE_) && (_SAFETY_VERIFYFUNCTION_ENABLE_)

// 发送超时                   - 250ms
#define FINGER_MESSAGE_SENGING_RATED_TIME                 (250ul)
// 时间补偿                   - 3s
#define FINGER_MESSAGE_TIME_BIAS                          (3ul)

// 录入指纹次数
#define FINGER_NUMBER_OF_FINGERPRINTING                   (3ul)
// 虚拟用户编码
#define FINGER_VIRTUAL_USER_CODE                          (0xFFFF)

/**
 * @brief 命令执行表
 *
 */
typedef enum
{
  FINGER_WAIT_READY,                     // 等待就绪
  FINGER_TRUE_ON_LED,                    // 打开 LED
  FINGER_TRUE_OFF_LED,                   // 关闭 LED
  FINGER_ENROLL_CANCEL,                  // 退出录取
  FINGER_DELETING_USERS,                 // 删除用户
  FINGER_INTO_POWER_DOWM,                // 进入掉电模式
  FINGER_GET_SERIAL_NUMBER,              // 获取序列号
  FINGER_UPLOAD_IMAGE_DATA,              // 上传图片数据
  FINGER_COMMUNICATION_TEST,             // 连接测试
  FINGER_GET_IDLE_USER_CODE,             // 获取空闲的用户编码
  FINGER_TRANSMIT_FILE_PACKET,           // 发送文件
  FINGER_GET_IMAGE_INFORMATION,          // 获取图像属性
  FINGER_INFORM_IMAGE_ATTRIBUTE,         // 告知图像属性
  FINGER_EXECUTE_FACTORY_RESET,          // 恢复出厂
  FINGER_GET_NUMBER_OF_TEMPLATE,         // 获取模板数量
  FINGER_GET_APPLICATION_VERSION,        // 获取固件版本号
  FINGER_IDENTIFY_USER_PERMISSIONS,      // 鉴定用户权限
  FINGER_USER_INTERACTIVE_REGISTRATION,  // 注册新用户交互模式
  FINGER_GET_WHETHER_THE_FINGER_PRESSED, // 获取是否按下指纹
} FingerStepsOfSending_t;

/**
 * @brief 报文解析结果
 *
 */
typedef enum
{
  FINGER_EXECUTE_OVER,                // 完毕
  FINGER_EXECUTE_WAIT,                // 等待
  FINGER_EXECUTE_ERROR,               // 错误
  FINGER_EXECUTE_RETRY,               // 重试
  FINGER_EXECUTE_SUCCESS,             // 成功
  FINGER_EXECUTE_USER_IS_FULL,        // 用户已满
  FINGER_EXECUTE_USER_ALREADY_EXISTS, // 用户已存在
} FingerExecuteResult_t;

/**
 * @brief 硬件属性
 *
 */
typedef struct
{
  uint8_t NumberOfUser;                                          // 已注册用户数数量
  char SerialNumber[FINGER_MODULE_SN_LENGTH];                    // 模组序列号
  char AlgorithmVersion[FINGER_LENGTH_OF_VERSION_INFORMATION];   // 算法版本
  char ApplicationVersion[FINGER_LENGTH_OF_VERSION_INFORMATION]; // 固件版本号
} FingerHardwareAttribute_t;

/**
 * @brief 文件操作状态
 *
 */
typedef struct
{
  uint8_t FileType;         // 文件类型
  uint32_t FileSize;        // 文件大小
  uint16_t TransmitterSize; // 发送数据长度
  uint32_t RequestFileSize; // 已接收文件大小
} FingerFileOperation_t;

/**
 * @brief 删除用户信息
 *
 */
typedef struct
{
  uint8_t NumberOfDelete;                             // 待删除用户数量
  uint16_t UserId[FINGER_NUMBER_OF_REGISTERED_USERS]; // 删除用户编码
} FingerDeleteUserInformation_t;

/**
 * @brief 事件状态位
 *
 */
typedef struct
{
  uint16_t TempUserId;
  FingerCommandType_t MessageId;         // 期待消息类型
  FingerProtocolCommand_t CommandToSend; // 发起命令类型
  FingerStepsOfSending_t StepsOfSending; // 执行步骤
} FingerEventStatus_t;

/**
 * @brief 人脸事件状态位
 *
 */
typedef struct
{
  FingerEventStatus_t EventStatus;                     // 事件处理状态
  FingerFileOperation_t FileOperation;                 // 文件收发状态
  FingerHardwareAttribute_t HardwareAttribute;         // 硬件属性
  FingerDeleteUserInformation_t DeleteUserInformation; // 待删除的用户信息
} FingerBitStatus_t;

/**
 * @brief 获取已注册用户数量
 *
 * @return uint8_t - 已注册用户数量
 */
extern uint8_t FingerGetTheNumberOfRegisteredUsers(void);

/**
 * @brief 获取设备序列号
 *
 * @param pSerialNumberOut - 模组序列号
 */
extern void FingerGetDeviceSerialNumber(char *pSerialNumberOut);

/**
 * @brief 获取模组固件版本号
 *
 * @param pVersionOut - 固件版本号
 */
extern void FingerGetApplicationVersion(char *pVersionOut);

/**
 * @brief 验证报文有效性
 *
 * @param pMessageIn - 待验证报文
 * @param pDataOOut  - 指向附带数据起始地址的指针变量
 * @param pSizeOut   - 附带数据长度
 * @param pResultOut - 响应结果
 * @return bool      - 验证状态（true：成功 false：失败）
 */
extern bool FingerValidateMessage(const void *pMessageIn, uint8_t *pDataOOut, uint16_t *pSizeOut, uint8_t *pResultOut);

/**
 * @brief 构建自检报文
 *
 * @param pMessageOut      - 构建后的报文
 * @param pSizeOut         - 构建后的报文长度
 * @param pResponseTimeOut - 报文发送超时时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FingerBuildSelfTestMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 构建恢复出厂设置报文
 *
 * @param pMessageOut      - 构建后的报文
 * @param pSizeOut         - 构建后的报文长度
 * @param pResponseTimeOut - 报文发送超时时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FingerBuildFactorySettingMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 构建获取特征值文件报文
 *
 * @param pMessageOut      - 构建后的报文
 * @param pSizeOut         - 构建后的报文长度
 * @param pResponseTimeOut - 报文发送超时时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FingerBuildGetEigenvalueFileMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 构建强制进入休眠报文
 *
 * @param pMessageOut      - 构建后的报文
 * @param pSizeOut         - 构建后的报文长度
 * @param pResponseTimeOut - 报文发送超时时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FingerBuildForcedToGotoSleepMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 构建在线注册用户报文
 *
 * @param pMessageOut      - 构建后的报文
 * @param pSizeOut         - 构建后的报文长度
 * @param pResponseTimeOut - 报文发送超时时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FingerBuildLocalRegisterUserMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 构建用户权限鉴定报文
 *
 * @param pMessageOut      - 构建后的报文
 * @param pSizeOut         - 构建后的报文长度
 * @param pResponseTimeOut - 报文发送超时时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FingerBuildUserAuthenticationMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 构建删除特定用户报文
 *
 * @param pMessageOut      - 构建后的报文
 * @param pSizeOut         - 构建后的报文长度
 * @param pResponseTimeOut - 报文发送超时时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FingerBuildDeletingSpecificUsersMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 构建通过特征值文件注册用户报文
 *
 * @param pMessageOut      - 构建后的报文
 * @param pSizeOut         - 构建后的报文长度
 * @param pResponseTimeOut - 报文发送超时时间
 * @return bool            - 构建状态（true：成功 false：失败）
 */
extern bool FingerBuildRegistrationByEigenvalueMessage(uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 解析设备自建报文
 * 
 * @param pDataIn       - 待解析报文
 * @param DataSize      - 待解析报文长度
 * @param ParsingResult - 报文解析结果
 * @return uint8_t      - 解析状态（true：成功 false：失败）
 */
extern uint8_t FingerParsingSelfTestMessage(const void *pDataIn, uint16_t DataSize, uint8_t ParsingResult);

/**
 * @brief 解析设备出厂设置报文
 * 
 * @param pDataIn       - 待解析报文
 * @param DataSize      - 待解析报文长度
 * @param ParsingResult - 报文解析结果
 * @return uint8_t      - 解析状态（true：成功 false：失败）
 */
extern uint8_t FingerParsingDeviceFactorySettingMessage(const void *pDataIn, uint16_t DataSize, uint8_t ParsingResult);

/**
 * @brief 解析设备强制进入休眠报文
 * 
 * @param pDataIn       - 待解析报文
 * @param DataSize      - 待解析报文长度
 * @param ParsingResult - 报文解析结果
 * @return uint8_t      - 解析状态（true：成功 false：失败）
 */
extern uint8_t FingerParsingForcedToGotoSleepMessage(const void *pDataIn, uint16_t DataSize, uint8_t ParsingResult);

/**
 * @brief 解析设备获取特征值文件报文
 * 
 * @param pDataIn       - 待解析报文
 * @param DataSize      - 待解析报文长度
 * @param ParsingResult - 报文解析结果
 * @return uint8_t      - 解析状态（true：成功 false：失败）
 */
extern uint8_t FingerParsingGetEigenvalueFileMessage(const void *pDataIn, uint16_t DataSize, uint8_t ParsingResult);

/**
 * @brief 解析设备本地注册用户报文
 * 
 * @param pDataIn       - 待解析报文
 * @param DataSize      - 待解析报文长度
 * @param ParsingResult - 报文解析结果
 * @return uint8_t      - 解析状态（true：成功 false：失败）
 */
extern uint8_t FingerParsingLocalRegisterMessage(const void *pDataIn, uint16_t DataSize, uint8_t ParsingResult);

/**
 * @brief 解析设备用户权限鉴定报文
 * 
 * @param pDataIn       - 待解析报文
 * @param DataSize      - 待解析报文长度
 * @param ParsingResult - 报文解析结果
 * @return uint8_t      - 解析状态（true：成功 false：失败）
 */
extern uint8_t FingerParsingUserAuthenticationMessage(const void *pDataIn, uint16_t DataSize, uint8_t ParsingResult);

/**
 * @brief 解析设备删除特定用户报文
 * 
 * @param pDataIn       - 待解析报文
 * @param DataSize      - 待解析报文长度
 * @param ParsingResult - 报文解析结果
 * @return uint8_t      - 解析状态（true：成功 false：失败）
 */
extern uint8_t FingerParsingDeletingSpecificUsersMessage(const void *pDataIn, uint16_t DataSize, uint8_t ParsingResult);

/**
 * @brief 解析设备通过特征值文件注册用户报文
 * 
 * @param pDataIn       - 待解析报文
 * @param DataSize      - 待解析报文长度
 * @param ParsingResult - 报文解析结果
 * @return uint8_t      - 解析状态（true：成功 false：失败）
 */
extern uint8_t FingerParsingRegistrationByEigenvalueMessage(const void *pDataIn, uint16_t DataSize, uint8_t ParsingResult);

/**
 * @brief 获取本地注册用户编码
 *
 * @return uint16_t - 用户编码
 */
extern uint16_t FingerGetLocalRegisterUserId(void);

/**
 * @brief 获取授权用户编码
 *
 * @return uint16_t - 用户编码
 */
extern uint16_t FingerGetAuthorizedUserCode(void);

/**
 * @brief 功能初始化
 *
 */
extern void FingerFunctionalInitialization(void);

/**
 * @brief 启动强制进入睡眠
 *
 */
extern void FingerStartForcedToGotoSleep(void);

/**
 * @brief 启动本地注册
 *
 * @param WaitTime - 等待时间
 */
extern void FingerStartLocalRegisterTasks(uint8_t WaitTime);

#endif
#endif
